import abiao_utils from "abiao_utils";
import Draw from "../../miniGames/draw.model";
import DrawLog from "../../miniGames/drawLog.model";
import Room from "../../miniGames/room.model";
import Redis from "../redis";
import utils from "../utils";
import socket from "./socket";

/**
 * @Author: 陈瑞鹏
 * @Date:   2022-11-02 13:45:01
 * @Last Modified by:   陈瑞鹏
 * @Last Modified time: 2023-10-30 17:41:36
 */
export default class room {

  /**
   * 加入房间
   * @param userInfo 
   * @param roomId 
   * @param sid 
   */
  static async join_room(userInfo: any, roomId: number, sid: string) {
    let room = "room_" + roomId;
    let roomRes: any = await Room.findOne({ roomId });
    // console.log(userInfo.roleId);
    let obj = roomRes.roomData || [];
    let bool = false;
    obj.forEach(element => {
      if (element.roleId == userInfo.roleId) {
        bool = true;
      }
    });
    if (!bool) {
      obj.push({
        roleId: userInfo.roleId, isReady: false, money: 0, nickName: userInfo['nickName'], iconUrl: userInfo['avatar']
      })
      await Room.updateOne({ roomId }, { roomData: obj });
    }

    socket.socketData.join(room);

    roomRes = await Room.findOne({ roomId });
    this.send_room_msg("message", { message: `${userInfo.nickName}进入房间${room}`, roomRes }, room);
  }

  /**
   * 离开房间
   * @param userInfo 
   * @param roomId 
   */
  static async leave_room(userInfo: any, roomId) {
    let room = "room_" + roomId;
    let roomRes: any = await Room.findOne({ roomId });
    if (roomRes.gameId == 5382) { //抽奖小游戏，人员断开，不离开房间
      this.send_room_msg("message", { message: `${userInfo.nickName}离开房间${room}`, roomRes }, room);
      return;
    }
    let obj = roomRes.roomData || [];
    let ownerId = roomRes.roleId;
    let isDisMiss = false;
    for (let i = 0; i < obj.length; i++) {
      if (obj[i].roleId == userInfo.roleId) {
        obj.splice(i, 1);
        if (userInfo.roleId == ownerId) { //如果房主离开
          if (obj.length > 0) {
            //房间里还有人的话
            ownerId = obj[0].roleId;
            obj[0].isReady = true;
          } else {
            isDisMiss = true; //解散房间
          }
        }
        break;
      }
    }
    await Room.updateOne({ roomId }, { roomData: obj, roleId: ownerId, isDisMiss });

    roomRes = await Room.findOne({ roomId });

    if (isDisMiss) {
      this.send_room_msg("disMiss", { message: `解散房间${room}`, roomRes }, room);
      socket.socketData.leave(room);
    } else {
      this.send_room_msg("message", { message: `${userInfo.nickName}离开房间${room}`, roomRes }, room);
    }
  }

  /**
   * 解散房间
   * @param roomId 
   */
  static async disMiss_room(roomId) {
    let room = "room_" + roomId;
    await Room.updateOne({ roomId }, { roomData: [] });

    let roomRes = await Room.findOne({ roomId });

    this.send_room_msg("disMiss", { message: `解散房间${room}`, roomRes }, room);
    socket.socketData.leave(room);
  }

  static async game_ready(userInfo, roomId) {
    let room = "room_" + roomId;
    let roomRes: any = await Room.findOne({ roomId });
    // console.log(userInfo.roleId);
    let obj = roomRes.roomData || [];
    for (let i = 0; i < obj.length; i++) {
      if (obj[i].roleId == userInfo.roleId) {
        obj[i].isReady = true;
        break;
      }
    }
    await Room.updateOne({ roomId }, { roomData: obj });

    this.send_room_msg("message", { message: `${room}_${userInfo.nickName}已准备`, roomRes }, room);
  }

  /**
   * 游戏开始
   * @param roomId 
   */
  static async game_start(roomId) {
    let room = "room_" + roomId;
    let roomRes: any = await Room.findOne({ roomId });

    await Room.updateOne({ roomId }, { round: roomRes.round + 1, isGameStart: true, downTime: 20 });

    Redis.hset(roomId, "downTime", "20");

    Redis.hset(roomId, "rddownTime", "3");

    this.send_room_msg("gameStart", { message: `游戏开始`, roomRes }, room);

    let that = this;

    for (let j = 0; j < roomRes.roomData.length;) {
      await Redis.hset(roomId, roomRes.roomData[j].roleId, "0");
      j++;
    }

    socket.downTimeHandlerArr["rd_" + room] = setInterval(async () => {
      let rddownTime = 3;
      await Redis.hget(roomId, "rddownTime").then((d) => {
        rddownTime = Number(d) - 1;
        Redis.hset(roomId, "rddownTime", `${rddownTime}`);
      })

      if (rddownTime <= 0) {
        socket.downTimeHandlerArr[room] = setInterval(async () => {
          let downTime = 20;
          await Redis.hget(roomId, "downTime").then((d) => {
            downTime = Number(d) - 1;
            Redis.hset(roomId, "downTime", `${downTime}`);
          })

          if (downTime <= 0) {

            let rRes: any = await Room.findOne({ roomId });

            let roomData = rRes.roomData || [];
            let isGameStart = rRes.isGameStart;

            for (let i = 0; i < roomData.length;) {
              await Redis.hget(roomId, roomData[i].roleId).then((d) => {
                roomData[i].money = d;

                i++;
              })
            }

            isGameStart = false;

            await Room.updateOne({ roomId }, { downTime, roomData, isGameStart });

            rRes = await Room.findOne({ roomId });

            that.send_room_msg("gameEnd", { message: `游戏结束`, roomRes: rRes }, room);

            clearInterval(socket.downTimeHandlerArr[room]);
          } else {
            // await Room.updateOne({ roomId }, { downTime });
          }

          that.send_room_msg("downTime", { message: `倒计时`, downTime }, room);
        }, 1000)

        clearInterval(socket.downTimeHandlerArr["rd_" + room]);
      }

      that.send_room_msg("rdDownTime", { message: `倒计时`, rdDownTime: rddownTime }, room);
    }, 1000);
  }

  /**
   * 抽奖开始
   * @param roomId 
   */
  static async draw_start(roomId) {

    // console.log(roleIdArr);
    let drawRes: any = await Draw.findOne({ roomId });
    if (!drawRes) {
      return;
    }
    let num = 0;
    let drawData = drawRes.drawData;
    drawData.forEach(element => {
      if (element) {
        num += element.number;
      }
    });

    let room = "room_" + roomId;
    let roomRes: any = await Room.findOne({ roomId });

    let roleIdArr = [];
    roomRes.roomData.forEach(element => {
      if (element && drawRes.excludeArr && drawRes.excludeArr.indexOf(element.roleId) == -1) {
        roleIdArr.push(element.roleId);
      }
    });

    let resultArr = [];
    let xs = 1;
    if (num > roleIdArr.length) {
      xs = roleIdArr.length / num;
    }

    drawData.forEach(element => {
      for (let i = 0; i < Math.max(1, Math.floor(element.number * xs)); i++) {
        resultArr.push({ id: element.id, roleId: null })
      }
    });

    //打乱数组
    roleIdArr = utils.shuffle(roleIdArr);
    // console.log(roleIdArr);
    resultArr.forEach((ele, i) => {
      if (ele && roleIdArr[i]) {
        ele.roleId = roleIdArr[i];
      }
    })

    await DrawLog.create({
      roomId,
      drawData,
      excludeArr: drawRes.excludeArr,
      roomData: roomRes.roomData,
      resultArr,
      roleIdArr,
      updateTime: abiao_utils.date(),
      createTime: abiao_utils.date(),
    })

    this.send_room_msg("drawStart", { message: `抽奖开始` }, room);

    let that = this;
    setTimeout(() => {
      that.send_room_msg("drawResult", { message: `抽奖结果`, resultArr, roleIdArr }, room);
    }, 5000);

  }

  /**
   * 房主退出
   * @param roomId 
   */
  static async draw_end(roomId) {

    let room = "room_" + roomId;

    this.send_room_msg("drawEnd", { message: `房主退出` }, room);

  }

  /**
   * 发送房间消息
   * @param event 
   * @param data 
   * @param room 
   */
  static send_room_msg(event: string, data: any, room: string) {
    // console.log("发送信息");
    socket.enterGameNamesape.to(room).emit(event, data);
  }
}